package com.coszero.utilslibrary.media;

import android.app.Activity;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.util.Log;

import com.coszero.utilslibrary.utils.LogX;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Desc： 音频池工具类,短音频,有缓存池
 *
 * @author xmqian
 * Email:xmqian93@163.com
 * Date: 2021/3/13 0013 17:16
 * <p>
 * SoundPoolUtils.playSoundWithRedId(R.raw.physical_kaishi);
 * @version 1
 */
public class SoundPoolUtils {
    private final String TAG = "soundPool";
    /**
     * 能够同时播放的最大音效数,最好不要设置太大
     * 同时播放是指正在播放音频时也可播放其它音频
     */
    private static final int MAX_STREAMS = 4;
    /**
     * 音频类型
     * STREAM_MUSIC 音乐音频,播放时使用媒体音量
     * STREAM_SYSTEM 系统音频,播放时使用铃声音量
     */
    private static final int STREAM_TYPE = AudioManager.STREAM_MUSIC;
    /**
     * 循环方式
     * -1 表示无限循环
     * 0 表示不循环
     * 其他  表示循环多少次
     */
    private final int LOOP = 0;
    /**
     * 指定播放声音的优先级，数值越高，优先级越大
     */
    private final int PRIORITY = 0;
    /**
     * 播放速率
     * 1.0的播放率可以使声音按照其原始频率，
     * 而2.0的播放速率，可以使声音按照其 原始频率的两倍播放。
     * 如果为0.5的播放率，则播放速率是原始频率的一半。
     * 播放速率的取值范围是0.5至2.0
     */
    private final float RATE = 1f;

    private SoundPool mainSoundPool;
    /**
     * 音频音量值 0 -> 1
     */
    private float volume = 1f;
    private int soundId;
    private int resId;
    private final Context mainContext;
    /**
     * 加载资源成功
     */
    private boolean isLoadResourceSuccess;
    /**
     * 用来保存临时加载的音频ID,防止同一个音频被反复加载消耗内存
     */
    private Map<Integer, Integer> soundIdsMap = new HashMap<>();

    public SoundPoolUtils(Context context) {
        this.mainContext = context;
        this.isLoadResourceSuccess = false;
        if (mainSoundPool == null) {
            init();
        }
    }

    /**
     * 播放音频
     *
     * @param resId 音频资源
     */
    public void playSoundWithRedId(int resId) {
        this.resId = resId;
        if (mainSoundPool == null) {
            init();
        }
        // 音频加载回调
        this.mainSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
            @Override
            public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                playSound();
            }
        });
        //判断字典中是否已加载过音频,加载过直接播放音频id,否则加载音频资源
        if (soundIdsMap.containsKey(resId)) {
            LogX.i(TAG, "已加载过该音频资源,直接播放");
            playSound(soundIdsMap.get(resId).intValue());
        } else {
            //load res
            this.soundId = this.mainSoundPool.load(this.mainContext, this.resId, 1);
            soundIdsMap.put(resId, soundId);
        }
    }

    /**
     * 初始化音频池
     */
    private void init() {
        // 音频管理器的音频设置调整音量
        AudioManager mainAudioManager = (AudioManager) this.mainContext.getSystemService(Context.AUDIO_SERVICE);
        // 当前音量
        float currentVolumeIndex = (float) mainAudioManager.getStreamVolume(STREAM_TYPE);
        // 获取最大音量
        float maxVolumeIndex = (float) mainAudioManager.getStreamMaxVolume(STREAM_TYPE);
        // 计算当前音量 (0 --> 1)
        this.volume = currentVolumeIndex / maxVolumeIndex;
        //设置音频控制器控制的音量类型
        ((Activity) this.mainContext).setVolumeControlStream(STREAM_TYPE);

        // API21(5.0)以上
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            AudioAttributes audioAttrib = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_GAME)
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .build();
            SoundPool.Builder builder = new SoundPool.Builder();
            builder.setAudioAttributes(audioAttrib).setMaxStreams(MAX_STREAMS);
            this.mainSoundPool = builder.build();
        } else {
            // SoundPool(同时播放最大数量, 音频类型, 0)
            this.mainSoundPool = new SoundPool(MAX_STREAMS, STREAM_TYPE, 0);
        }
    }

    /**
     * 播放音频
     */
    private void playSound() {
        isLoadResourceSuccess = true;
        playSound(this.soundId);
    }

    /**
     * @param soundId 返回的音频ID,使用load()方法生成Id
     */
    public void playSound(int soundId) {
        if (!isLoadResourceSuccess) {
            Log.e(TAG, "请先加载音频资源");
            return;
        }
        float leftVolumn = volume;
        float rightVolumn = volume;
        //play(返回的音频ID,左声道音量,右声道音量,播放声音优先级(数值越高优先级越大),是否循环,播放速率)
        this.mainSoundPool.play(soundId, leftVolumn, rightVolumn, PRIORITY, LOOP, RATE);
    }

    /**
     * 加载音频数据
     *
     * @param resourceList 音频资源
     * @return 返回加载音频后的Id列表
     */
    public List<Integer> load(List<Integer> resourceList) {
        if (resourceList == null && resourceList.size() == 0) {
            isLoadResourceSuccess = false;
            return new ArrayList<>();
        }
        //这里去除加载完成的监听
        this.mainSoundPool.setOnLoadCompleteListener(null);
        List<Integer> soundIds = new ArrayList<>();
        for (int i = 0; i < resourceList.size(); i++) {
            int loadId = this.mainSoundPool.load(mainContext, resourceList.get(i), 1);
            soundIds.add(loadId);
        }
        isLoadResourceSuccess = true;
        return soundIds;
    }

    /**
     * @return 返回对象
     */
    public SoundPool getMainSoundPool() {
        if (mainSoundPool == null) {
            init();
        }
        return mainSoundPool;
    }

    /**
     * 释放资源
     */
    public void release() {
        soundIdsMap.clear();
        if (mainSoundPool != null) {
            mainSoundPool.release();
            mainSoundPool = null;
            isLoadResourceSuccess = false;
        }
    }
}
